<?php
/*=============================================================================
|| ##################################################################
||	phpFoX Konsort
|| ##################################################################
||
||	Copyright		: (C) 2005-2007 PHPFOX Limited a Reality Fox Creation
||	Contact			: info@phpfox.com
||
||	- phpFoX and all of its source code and files are protected by Copyright Laws.
||
||	- The license for phpFoX permits you to install this software on a single domain (.com, .org, .net, etc.).
||
||	- You may also not remove this copyright screen which shows the copyright information and credits for phpFoX (RealityFOX Creations).
||
||	- phpFoX Konsort is NOT a FREE software - http://www.phpfox.com/license/
||
|| ##################################################################
=============================================================================*/

/* $File: ./include/modules/Log/classes/PhpFox_ServiceLog.class.php, $Author:  $ */



/** Service for working with logs
 *
 * @package module.log
 * @version $Id: PhpFox_ServiceLog.class.php 469 2008-06-11 21:12:06Z phpfoxsv $
 *
 */
class PhpFox_Mod_Log_ServiceLog extends BaseService
{
    function getUserSession($sGet = 'online_session_id')
    {
    	static $aRow;
    	
    	if (isset($aRow[$sGet])) 
    	{
    		return $aRow[$sGet];
    	}
    	
    	$iSessId = $this->_oModule->getSessVar('online_session', 0);
    	$oDb =& Database::get();
		$aRow = $oDb->getRow("
			SELECT
				" . $sGet . "
			FROM " . App::getT('online_session') . " 
			WHERE online_session_id = '" . $iSessId . "'
		");
    	
		return (isset($aRow[$sGet]) ? $aRow[$sGet] : array());
    }
	
	
	/** Adds site session record
     *
     * @param PhpFox_ModAccount_ItemAccount $oUser current user or null if visitor
     */
    function addSiteSession($oUser)
    {
    	if($this->_isLoginByAdmin())
    		return true;
        //add/update online session record
        $this->_addOnlineSession($oUser);

        if (! App::getSetting('do_site_session'))
        {
            //site sessions tracking is turn off by admin
           return;
        }

        //site session table
        $sUserName = $oUser ? $oUser->aData['user'] : '';
        $oSiteSess = &$this->_oModule->getItem('SiteSession');
        /* @var $oSiteSess PhpFox_Mod_Log_ItemSiteSession */

	    if ( !in_array(App::getPageName(), App::getParam('Mod_Log.exclude_pages')) )
        {
            $oSiteSess->aData = array(
                'user'     => $sUserName,
                'ip'       => $_SERVER['REMOTE_ADDR'],
                'browser'  => $_SERVER['HTTP_USER_AGENT'],
                'host'     => (isset($_SERVER['REMOTE_HOST']) ? $_SERVER['REMOTE_HOST'] : ''),
                'time'     => time(),
                'page'     => (isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''),
                //'port'     => $_SERVER['REMOTE_PORT'],
                'protocal' => $_SERVER['REQUEST_METHOD'],
                'refer'    => isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : '',
            );
            $oSiteSess->insert();
        }
    }

    /** Add page view record
     *
     * @param string                        $sPage page name
     * @param PhpFox_ModAccount_ItemAccount $oUser current user
     */
    function addPageView($sPage, $oUser)
    {
        if($this->_isLoginByAdmin())
    		return true;
        if ( (!in_array($sPage, App::getParam('Mod_Log.log_pages'))) ||
             $this->_isPageExcluded($sPage))
        {
            return;
        }

		if ( phpfoxCache )
		{
    		if ( empty($oUser->aData['user']) )
    		{
    			return;
    		}

			App::loadClass('Database');
    		$oDb = &Database::get();
    		$sUser = $oUser->aData['user'];

    		$page = $oDb->getRow('SELECT COUNT(*) AS count FROM '. App::getT('page') .' WHERE user = "'. $sUser .'" AND page = "'. $sPage .'"');
    		if ( $page['count'] )
    		{
        	    $oDb->query("UPDATE ". App::getT('page') ." SET time = '". time() ."' WHERE user = '". $sUser ."' AND page = '". $sPage ."'");
    		}
    		else
    		{
    			$oDb->query("INSERT INTO ". App::getT('page') ." SET
    				time = '". time() ."',
    				user = '". $sUser ."',
    				page = '". $oDb->escape($sPage) ."'");
    		}
		}
		else
		{
        	$oPage = $this->_oModule->getItem('Page');
        	/* @var $oPage PhpFox_Mod_Log_ItemPage */
        	$sUser = $oUser->aData['user'];
        	if ($oPage->loadByCondition('user = "'.$sUser.'" AND page = "'.$sPage.'"'))
        	{
        	    //update page view time
        	    $oPage->aData['time'] = time();
        	    $oPage->update(array('time'));
        	}
        	else
        	{
        	    $oPage->aData = array(
        	        'user' => $sUser,
        	        'page' => $sPage,
        	        'time' => time(),
        	    );
        	    $oPage->insert();
	        }
	 	}
    }

    /** Add profile view
     *
     * @param PhpFox_ModAccount_ItemAccount $oCurrUser current user (who view)
     * @param PhpFox_ModAccount_ItemAccount $oOwner    profile owner
     */
    function addProfileView($oCurrUser, $oOwner)
    {
        if($this->_isLoginByAdmin())
    		return true;
        $oProfileView = $this->_oModule->getItem('ProfileView');
        /* @var $oProfileView PhpFox_Mod_Log_ItemProfileView */

        $sUser  = $oCurrUser->aData['user'];
        $sOwner = $oOwner->aData['user'];
        if ($sUser == $sOwner) //do not monitor self-profile viewing
        {
            return;
        }

		if ( empty($sUser) || empty($sOwner) )
		{
			return;
		}

        if ($oProfileView->loadByCondition('user = "'.$sUser.'" AND viewing = "'.$sOwner.'"'))
        {
            //update page view time
            $oProfileView->aData['time'] = time();
            $oProfileView->update(array('time'));
        }
        else
        {
            $oProfileView->aData = array(
                'user'    => $sUser,
                'viewing' => $sOwner,
                'time'    => time(),
            );
            $oProfileView->insert();
        }
    }

    /** Is exclude page from logs
     *
     * @param string $sPage page name (logical)
     * @return bool true - exclude, false - include
     */
    function _isPageExcluded($sPage)
    {
        foreach(App::getParam('Mod_Log.exclude_pages') as $sExclPage)
        {
            if ($sPage == $sExclPage)
            {
                return true;
            }
        }

        return false;
    }

    /** Clears all site sessions
     *
     */
    function clearSiteSessions()
    {
        $oSiteSess = &$this->_oModule->getItem('SiteSession');
        $oSiteSess->oDb->query('TRUNCATE TABLE '.$oSiteSess->sTable);
    }

    /** Return recent visitors for given page
     *
     * @param string $sPage    page name
     * @param int    $iNumUser users limit to select
     * @return array users list
     */
    function getRecentUserList($sPage, $iNumUsers)
    {
        $oPage = $this->_oModule->getItem('Page');
        $aUsers = $oPage->oDb->getRows('SELECT user FROM '.$oPage->sTable.
                                       '  WHERE page = "'.$sPage.'" '.
                                       '  ORDER BY `time` DESC '.
                                       '  LIMIT '.$iNumUsers);


        return $aUsers;
    }

    /** Return recent visitors for profile page
     *
     * @param string $sUser    profile user name
     * @param int    $iNumUser users limit to select
     * @return array users list
     */
    function getRecentUserForProfile($sUser, $iNumUsers)
    {
        $oProfileView = $this->_oModule->getItem('ProfileView');
        $aUsers = $oProfileView->oDb->getRows('SELECT user FROM '.$oProfileView->sTable.
                                       '  WHERE viewing = "'.$sUser.'" '.
                                       '  ORDER BY `time` DESC '.
                                       '  LIMIT '.$iNumUsers);


        return $aUsers;
    }


    /** Get site statistics
     *
     * @return array site statistics
     */
    function getSiteStat()
    {
        $oDb = &Database::get();
        $oAcc = &App::getModuleItem('Account', 'Account'); //need this to load module-realted config

        $aRes = array
        (
            'all_members'   => $oDb->getField('SELECT COUNT(*) FROM `'.$oAcc->sTable.'` WHERE user != ""'),
            'online_member' => $oDb->getField('SELECT COUNT(DISTINCT  online_session_user) FROM `'.App::getT('online_session').'` WHERE online_session_user NOT LIKE "<g>%</g>"')
        );
		$aRes['online_all'] = $aRes['online_member'] + $oDb->getField('SELECT COUNT(*) FROM `'.App::getT('online_session').'` WHERE online_session_user LIKE "<g>%</g>"');
        return $aRes;
    }

    /** Get who's online info
     *
     * @param int $iLimit limit for last online users
     * @return array who's online info ($aLastOnline, $iOnlineMembers, $iOnlineUsers)
     */
    function getWhosOnlineInfo($iPageSize, $iPage)
    {
        $oSess = $this->_oModule->getItem('OnlineSession');

		$sSql = 'SELECT COUNT(DISTINCT online_session_user, online_session_page, online_session_ip) '.
                    ' FROM `'.$oSess->sTable.'` AS '.$oSess->sAlias;
        $iCnt = $oSess->oDb->getField($sSql);

    	$aItems = array();
        if ($iCnt)
        {
            $iOffset = $oSess->_getOffset($iPage, $iPageSize, $iCnt);
            $sSql = 'SELECT online_session_user, online_session_page, online_session_ip, online_session_time, u.user'.
                    ' FROM `'.$oSess->sTable.'` AS '.$oSess->sAlias.
                    ' 	LEFT JOIN ' . App::getT('user') . ' AS u ON(online_session_user = u.user)'.
                   	' GROUP BY ' . $oSess->sAlias . '.online_session_user '.
                    ' ORDER BY ' . $oSess->sAlias . '.online_session_time DESC '.
                   ($iPageSize?(' LIMIT '.$iOffset.','.$iPageSize):'');

            $aItems = $oSess->oDb->getRows($sSql);
            foreach ($aItems as $iKey => $aItem) 
            {
            	if (preg_match("/\<g\>(.*?)\<\/g\>/i", $aItem['online_session_user']))
            	{
            		$aItems[$iKey]['online_session_user'] = '';
            	}
				
            	$sCachedPage = '';
				foreach(App::getParam('Mod_Log.replace_pages') as $sKey => $sValue)
				{
					if ( eregi($sKey, $aItems[$iKey]['online_session_page']) )
					{
						$sCachedPage = $sValue;
						break;
					}
				}

				$aItems[$iKey]['online_session_page_display'] = (!empty($sCachedPage) ? App::format($sCachedPage) : $aItems[$iKey]['online_session_page']);            	
            }
        }    
		$iMembers = $oSess->oDb->getField(
                      ' SELECT COUNT(DISTINCT online_session_user)'.
                      ' FROM '. App::getT('online_session') .' AS s'.
                      ' 	JOIN ' . App::getT('user') . ' AS u ON (s.online_session_user = u.user)');

		return array($aItems, $iCnt, $iMembers, ($iCnt - $iMembers) );
    }

    /** Add/update online session record
     *
     * @param PhpFox_Mod_Accpunt_ItemAccount $oUser current user (not null)
     */
    function _addOnlineSession($oUser)
    {
    	if (!CAN_SET_COOKIE)
    	{
    		return;
    	}
    	
    	$iSessId = $this->_oModule->getSessVar('online_session', 0);
	
    	$iMaxId = $this->oDatabase->getField('SELECT `online_session_id` FROM '. $this->oDatabase->getT('online_session').'');
    	if ( $iMaxId> 2147483640)
    	{
    		$this->oDatabase->query("TRUNCATE TABLE `". App::getT('online_session') ."`");
    	}else{
    		
		$iTimeout = time() - App::getSetting('max_time_online') * 60;
		$this->oDatabase->query('DELETE FROM '. $this->oDatabase->getT('online_session').
                                 ' WHERE online_session_time < '.$iTimeout);
        }
		
		if ( $iSessId )
		{
			if (App::getUser('user'))
			{
				$iCheckUSession = $this->oDatabase->getField("SELECT COUNT(*) FROM ". $this->oDatabase->getT('online_session') ." WHERE online_session_user='". App::getUser('user') ."'");
				if ($iCheckUSession > 1)
				{
					$this->oDatabase->_delete(App::getT('online_session'), "online_session_user='". App::getUser('user') ."' LIMIT " . ($iCheckUSession-1));
				}
			}
			else 
			{
				$iCheckUSession = $this->oDatabase->getField("SELECT COUNT(*) FROM ". $this->oDatabase->getT('online_session') ." WHERE online_session_id='". $iSessId ."'");
			}
		}
		
		$bIsAdminSession = ((isset($_SESSION['Mod_Account']['by_admin']) && $_SESSION['Mod_Account']['by_admin']) ? true : false);
		
        if (isset($iCheckUSession) && $iCheckUSession)
        {
        	if ( in_array(App::getPageName(), App::getParam('Mod_Log.exclude_pages')) )
        	{
        		return;
        	}

            //got session -- update
            $aInfo = array();
            $aInfo['online_session_user']   = $oUser ? $oUser->aData['user'] : '<g>' . $iSessId . '</g>';
            $aInfo['online_session_status'] = $oUser ? $oUser->aData['type'] : '';
            $aInfo['online_session_ip']     = $_SERVER['REMOTE_ADDR'];
            $aInfo['online_session_staff']  = $oUser ? (($oUser->aData['type'] <= 1) ? '1' : '0') : '0';
            $aInfo['online_session_detail'] = $oUser ? $oUser->aData['password'] : '';
			$aInfo['online_session_page'] = App::getPage();
			$aInfo['online_session_time'] = time();
			$aInfo['online_session_login'] = ($bIsAdminSession ? 1 : 0);
			$this->oDatabase->update(App::getT('online_session'), $aInfo, "online_session_id = '". $iSessId ."'");
        }
        else
        {
            //no session -- add one
            $aInfo = array();
            $aInfo['online_session_detail'] = $oUser ? $oUser->aData['password'] : '';
            $aInfo['online_session_page'] = App::getPage();
            $aInfo['online_session_user']   = $oUser ? $oUser->aData['user'] : '<g>' . (rand(1, 1000) . time()) . '</g>';
            $aInfo['online_session_status'] = $oUser ? $oUser->aData['type'] : '';
            $aInfo['online_session_ip']     = $_SERVER['REMOTE_ADDR'];
            $aInfo['online_session_time'] = time();
            $aInfo['online_session_staff']  = $oUser ? (($oUser->aData['type'] <= 1) ? '1' : '0') : '0';
            $aInfo['online_session_login'] = ($bIsAdminSession ? 1 : 0);
            $this->oDatabase->insert(App::getT('online_session'), $aInfo);

            $this->_oModule->setSessVar('online_session', $this->oDatabase->getLastID());
            
            if ($oUser && !empty($oUser->aData['user']))
            {
            	$iLoginTime = time();
            	$_SESSION['phpFox']['sRandId'] = md5($iLoginTime . md5($oUser->aData['user']));
            	$this->oDatabase->update(App::getT('user'), array('login' => $iLoginTime), "user = '" . $oUser->aData['user'] . "'");	
            }            
        }
    }

    /** Update online status (offline and online)
     *
     */
    function _updateOnlineStatus()
    {
        $oUser = App::getModuleItem('Account', 'Account');
        $sSql = 'UPDATE '.$oUser->sTable.' u, online_session os '.
                '  SET u.user_online = "" '.
                '  WHERE u.user_online = "1" AND u.user <> os.online_session_user';
        $oUser->oDb->query($sSql);    

        $sSql = 'UPDATE '.$oUser->sTable.' u, online_session os '.
                '  SET u.user_online = "1" '.
                '  WHERE u.user_online = "" AND u.user = os.online_session_user';
        $oUser->oDb->query($sSql);    
        
    }

    /** Is user online
     *
     * @param PhpFox_Mod_Account_ItemAccount
     */
    function isOnline($oUser)
    {
        $oOnlineSess = $this->_oModule->getItem('OnlineSession');
        if ($oOnlineSess->loadByCondition('online_session_user ="'.$oUser->aData['user'].'"'))
        {
            $iTimeout = time() - App::getParam('Mod_Log.session_timeout');
            return ($iTimeout < $oOnlineSess->aData['online_session_time']);
        }

        return false;
    }

    /** OnLogout callback hanlder.
     *
     * @param array aParams callback paramters
     * @return bool true
     */
    function onLogout($aParams)
    {
        $oUser = $aParams['oUser'];
        if ($oUser)
        {
            $oOnlineSess = $this->_oModule->getItem('OnlineSession');
            $sSql = 'DELETE FROM '.$oOnlineSess->sTable.
                    '  WHERE online_session_user ="'.$oUser->aData['user'].'"';
            $oOnlineSess->oDb->query($sSql);
            $this->_oModule->setSessVar('online_session', 0);
        }
        return true;
    }

    /** OnDeleteAccount callback handler
     *
     * @param array aParams callback paramters
     * @return bool true
     */
    function onDeleteAccount($aParams)
    {
        $oAcc = $aParams['oAcc'];
        $aIds = $aParams['aIds'];
        foreach($aIds as $iId)
        {
            if ($oAcc->load($iId))
            {
                $sUser = $oAcc->aData['user'];
                //$sSql = 'DELETE FROM '.App::getT('online').' WHERE user = "'.$sUser.'"'; //??? old table, no used in phpfox16
                //$oAcc->oDb->query($sSql);
                $sSql = 'DELETE FROM '.App::getT('page').' WHERE user = "'.$sUser.'"';
                $oAcc->oDb->query($sSql);
                $sSql = 'DELETE FROM '.App::getT('session').' WHERE user = "'.$sUser.'" OR viewing="'.$sUser.'"';
                $oAcc->oDb->query($sSql);
                $sSql = 'DELETE FROM '.App::getT('site_session').' WHERE user = "'.$sUser.'"';
                $oAcc->oDb->query($sSql);
                $sSql = 'DELETE FROM '.App::getT('online_session').' WHERE online_session_user = "'.$sUser.'"';
                $oAcc->oDb->query($sSql);
            }
        }
    }
    
    function _isLoginByAdmin()
    {
    	return (isset($_SESSION['Mod_Account']['by_admin']) AND $_SESSION['Mod_Account']['by_admin']);
    }
}
?>